package com.shockweb.common.virtualconn;
import java.util.List;
import java.util.Map;
import java.util.HashMap;
import java.util.Iterator;

import com.shockweb.common.log.*;
import com.shockweb.common.virtualconn.connection.VirtualConnection;
import com.shockweb.common.virtualconn.factory.ConnentionFactory;
/**
 * 虚拟化连接池管理类，管理多个不同的连接池
 * 支持多个URL负载均衡，提供高可靠和高可用性
 * 仅做一些较小的开发工作量，能管理各种链接，包括数据库、密码机、MQ、webService、socket等
 * @author 彭明华
 * 2017-8-7 创建
 */
public class ConnectionPoolManager {

	/**
	 * 连接地址
	 */
	private Map<String,ConnectionPool<?>> connectionPools = new HashMap<String,ConnectionPool<?>>();
	
	/**
	 * 锁对象
	 */
	private final Object LOCK = new Object();
	/**
	 * 隐藏构造方法
	 */
	private ConnectionPoolManager(){
		
	}
	/**
	 * 单例管理
	 */
	private static ConnectionPoolManager manager = new ConnectionPoolManager();
	/**
	 * 获取ConnectionPoolManager单例
	 * @return
	 */
	public static synchronized ConnectionPoolManager getInstance(){
		return manager;
	}
	
	
    /**
     * 添加一个连接池
     * @param name
     * @param config
     * @param connentionFactorys
     * @throws VirtualConnException
     */
    public <T extends VirtualConnection> void addConnectionPool(String name,ConnectionPoolConfig config,List<ConnentionFactory<T>> connentionFactorys)throws VirtualConnException {
    	synchronized(LOCK){
    		if(connectionPools.containsKey(name)){
    			throw new VirtualConnException("'" + name + "'连接池已经存在，connectionPool:" + connectionPools.get(name));
    		}
    		ConnectionPool<?> pool = new ConnectionPool<T>(name,config,connentionFactorys);
    		new Thread(pool).start();
    		connectionPools.put(name, pool);
    	}
    }
    
    /**
     * 删除一个连接池
     * @param name
     * @throws VirtualConnException
     */
    public void removeConnectionPool(String name)throws VirtualConnException {
    	synchronized(LOCK){
    		connectionPools.remove(name);
    	}
    }
    
    /**
     * 获取连接池
     * @param name
     * @return 
     * @throws VirtualConnException
     */
    public ConnectionPool<?> getConnectionPool(String name)throws VirtualConnException {
    	synchronized(LOCK){
    		return connectionPools.get(name);
    	}
    }
    
    /**
     * 释放连接池
     */
    public void destory() {
    	synchronized(LOCK){
        	Iterator<String> iterators = connectionPools.keySet().iterator();
            while (iterators.hasNext()) {
            	String name = iterators.next();
            	ConnectionPool<?> pool = connectionPools.get(name);
                try {
                	pool.destory();
                }catch (Exception e) {
                	LogManager.errorLog(this.getClass(), "Can't destory ConnectionPool for pool " + name,e);
                }
            }
            connectionPools.clear();
    	}
    }
    
    
}
